package com.softaria.spkiller.mojo;

import java.util.ArrayList;
import java.util.Collection;

import org.apache.maven.plugin.MojoExecutionException;

import com.softaria.spkiller.analyzer.hierarchy.HierarchyProblemCollector;
import com.softaria.spkiller.layers.LayerIdentifier;
import com.softaria.spkiller.metadata.ClassIdentifier;

public class MojoHierarchyProblemCollector implements HierarchyProblemCollector {

	private class BrokenHierarchy {
		private ClassIdentifier classID;
		private ClassIdentifier parent1;
		private ClassIdentifier parent2;
		
		public BrokenHierarchy(ClassIdentifier classID,
				ClassIdentifier parent1, ClassIdentifier parent2) {
			super();
			this.classID = classID;
			this.parent1 = parent1;
			this.parent2 = parent2;
		}

		@Override
		public String toString() {
			return "Broken Hierarchy =" + classID + " has more than on parent, parent1="
					+ parent1 + ", parent2=" + parent2;
		}
		
		
	}
	
	private LayerIdentifier layerID;
	private Collection<BrokenHierarchy> brokenHierarchies = new ArrayList<MojoHierarchyProblemCollector.BrokenHierarchy>();
	private boolean noRoot = false;
	private int hierarchyCount = 1;
	private Collection<Collection<ClassIdentifier>> cycles = new ArrayList<Collection<ClassIdentifier>>();

	public MojoHierarchyProblemCollector(LayerIdentifier layerID) {
		this.layerID = layerID;
	}

	public void reportBrokenHierarchy(ClassIdentifier classID,
			ClassIdentifier parent1, ClassIdentifier parent2) {
		brokenHierarchies.add(new BrokenHierarchy(classID, parent1, parent2));

	}

	public void reportNoHierarchyRoot() {
		noRoot = true;
	}

	public void reportMultipleHierarchies(int hierarchyCount) {
		this.hierarchyCount = hierarchyCount;
	}

	public void check() throws MojoExecutionException{
		if(noRoot) {
			System.out.println("SPAGHETTI-KILLER ERROR: Hierarchical layer "+layerID+" has no root!");
		}
		if(hierarchyCount>1) {
			System.out.println("SPAGHETTI-KILLER WARNING: Hierarchical layer "+layerID+" has more than on hierarchies: "+hierarchyCount);
		}
		
		for(BrokenHierarchy bh:brokenHierarchies) {
			System.out.println("SPAGHETTI-KILLER ERROR: Hierarchical layer "+layerID+" has "+bh.toString());
		}
		
		for(Collection<ClassIdentifier> cycledClasses:cycles) {
			StringBuffer classes = new StringBuffer();
			
			for(ClassIdentifier classID:cycledClasses) {
				classes.append("\r\n");
				
				classes.append(classID.toString());
			}
			
			System.err.println("SPAGHETTI-KILLER ERROR: Hierarchical layer "+layerID+" has cycle: " + classes.toString());
		}
		
		if((noRoot) || (!brokenHierarchies.isEmpty())||(!cycles.isEmpty())) {
			throw new MojoExecutionException("Layer "+layerID+" appears not to be hierarchical. See above for details");
		}
		
	}

	public void reportCycle(Collection<ClassIdentifier> allClasses) {
		cycles.add(allClasses);
		
	}

}
